package com.ict.web.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.collect.Lists;
import com.ict.common.constant.UserConstants;
import com.ict.common.core.domain.entity.SysDept;
import com.ict.common.core.domain.entity.SysRole;
import com.ict.common.core.domain.entity.SysUser;
import com.ict.common.core.domain.model.LoginUser;
import com.ict.common.utils.SecurityUtils;
import com.ict.common.utils.StringUtils;
import com.ict.system.domain.SysUserRole;
import com.ict.system.mapper.SysUserRoleMapper;
import com.ict.system.service.ISysDeptService;
import com.ict.system.service.ISysUserService;
import com.ict.web.constant.Constants;
import com.ict.web.controller.file.domain.YzqFile;
import com.ict.web.controller.file.service.IYzqFileService;
import com.ict.web.domain.ExpertInformationSheet;
import com.ict.web.domain.OrganizationManagement;
import com.ict.web.domain.ProfessionalQualification;
import com.ict.web.domain.TechnicalTitle;
import com.ict.web.dto.ExpertInformationSheetDto;
import com.ict.web.dto.InsertExpertInformationSheetDto;
import com.ict.web.dto.QueryExpertInformationSheetDto;
import com.ict.web.dto.UpdateExpertInformationSheetDto;
import com.ict.web.mapper.ExpertInformationSheetMapper;
import com.ict.web.mapper.OrganizationManagementMapper;
import com.ict.web.mapper.ProfessionalQualificationMapper;
import com.ict.web.mapper.TechnicalTitleMapper;
import com.ict.web.service.*;
import com.ict.web.vo.ExpertInformationSheetDetailVo;
import com.ict.web.vo.ExpertInformationSheetListVo;
import com.ict.web.vo.ExpertMessageVo;
import com.ict.web.vo.ExtractRuleBeginVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.List;
import java.util.stream.Collectors;

import static com.ict.common.utils.PageUtils.startPage;

/**
 * 专家库信息Service业务层处理
 *
 * @author liujie
 * @date 2022-02-23
 */
@Service
public class ExpertInformationSheetServiceImpl extends ServiceImpl<ExpertInformationSheetMapper,ExpertInformationSheet> implements IExpertInformationSheetService
{
    @Resource
    private ExpertInformationSheetMapper expertInformationSheetMapper;
    @Resource
    private IExpertInformationSheetService expertInformationSheetService;
    @Resource
    private IProfessionalQualificationService qualificationService;
    @Resource
    private ITechnicalTitleService technicalTitleService;
    @Resource
    private ISysUserService userService;
    @Resource
    private  TechnicalTitleMapper technicalTitleMapper;
    @Resource
    private ProfessionalQualificationMapper qualificationMapper;
    @Resource
    private ISysDeptService deptService;
    @Resource
    private OrganizationManagementMapper organizationManagementMapper;
    @Autowired
    private IOrganizationManagementService organizationManagementService;
    @Resource
    private IYzqFileService fileService;
    @Resource
    private IReviewTaskService reviewTaskService;
    @Resource
    private SysUserRoleMapper sysUserRoleMapper;

    @Override
    public ExpertInformationSheetDetailVo getInfoByUserId() {
        Long userId = SecurityUtils.getUserId();
        List<SysRole> roles = SecurityUtils.getLoginUser().getUser().getRoles();
        List<Long> collect = roles.stream().map(SysRole::getRoleId).collect(Collectors.toList());
        Assert.isTrue(collect.contains(Constants.ROLE_TYPE_EXPERT),"该用户的部门不属于评审专家");
        return expertInformationSheetMapper.getInfoByUserId(userId);
    }

    /**
     * 查询专家库信息
     *
     * @param expertId 专家库信息主键
     * @return 专家库信息
     */
    @Override
    public ExpertInformationSheetDetailVo selectExpertInformationSheetByExpertId(Long expertId)
    {
        ExpertInformationSheetDetailVo expertInformationSheetDetailVo = expertInformationSheetMapper.selectExpertInformationSheetByExpertId(expertId);
        YzqFile haCertificateFile = fileService.getById(expertInformationSheetDetailVo.getHaCertificateFile());
        expertInformationSheetDetailVo.setHaCertificateFileDoc(haCertificateFile);
        YzqFile workUnitOpinionsFile = fileService.getById(expertInformationSheetDetailVo.getWorkUnitOpinionsFile());
        expertInformationSheetDetailVo.setWorkUnitOpinionsFileDoc(workUnitOpinionsFile);
        YzqFile idCardFile = fileService.getById(expertInformationSheetDetailVo.getIdCardFile());
        expertInformationSheetDetailVo.setIdCardFileDoc(idCardFile);
        YzqFile personalPhotosFile = fileService.getById(expertInformationSheetDetailVo.getPersonalPhotosFile());
        expertInformationSheetDetailVo.setPersonalPhotosFileDoc(personalPhotosFile);
        List<ProfessionalQualification> qualifications = expertInformationSheetDetailVo.getQualifications();
        List<TechnicalTitle> technicalTitles = expertInformationSheetDetailVo.getTechnicalTitles();
        if (!qualifications.isEmpty()) {
            qualifications.forEach(s->{
                YzqFile qualificationFile = fileService.getById(s.getQualificationFile());
                s.setQualificationFileDoc(qualificationFile);
            });
        }
        if (!technicalTitles.isEmpty()) {
            technicalTitles.forEach(s->{
                YzqFile technicalFile = fileService.getById(s.getTechnicalFile());
                s.setTechnicalFileDoc(technicalFile);
            });
        }
        //返回专家评审任务信息
        List<ExpertMessageVo> expertMessageVos = reviewTaskService.expertMessage(expertId);
        BigDecimal sum = new BigDecimal(0);
        if (!expertMessageVos.isEmpty()){
            for (ExpertMessageVo expertMessageVo : expertMessageVos) {
                BigDecimal totalScore = new BigDecimal(expertMessageVo.getTotalScore());
                sum = sum.add(totalScore);
            }
            BigDecimal averageScore = sum.divide(new BigDecimal(expertMessageVos.size()), 2, BigDecimal.ROUND_HALF_UP);
            expertInformationSheetDetailVo.setAverageScore(averageScore);
        }
        expertInformationSheetDetailVo.setExpertMessageVoList(expertMessageVos);
        return expertInformationSheetDetailVo;
    }

    /**
     * 查询专家库信息列表
     *
     * @param expertInformationSheet 专家库信息
     * @return 专家库信息
     */
    @Override
    public List<ExpertInformationSheetDetailVo> selectExpertInformationSheetList(ExpertInformationSheet expertInformationSheet,Long ormId,List<Long> expertIds)
    {
        return expertInformationSheetMapper.selectExpertInformationSheetList(expertInformationSheet,ormId,expertIds);
    }

    /**
     * 获取专家年龄
     * @param idNumber
     * @return
     */
    private static int getAge(String idNumber) {
        String birthday = idNumber.substring(6, 14);
        Calendar now = Calendar.getInstance();
        int nowYear = now.get(Calendar.YEAR);
        int nowMonth = (now.get(Calendar.MONTH)+1);
        int nowDay = now.get(Calendar.DAY_OF_MONTH);

        int year = Integer.valueOf(birthday.substring(0, 4));
        Assert.isTrue(LocalDateTime.now().getYear()>year,"身份证出生年月输入有误");
        int month = Integer.valueOf(birthday.substring(4, 6));
        int day = Integer.valueOf(birthday.substring(6));


        int age = nowYear - year;
        if (age <= 0 || age >= 100) {
            return -1;
        }
        if (nowMonth - month > 0) {
            return age;
        }
        if (nowMonth - month == 0) {
            if (nowDay - day >= 0) {
                return age;
            }
        }
        return age - 1;
    }

    /**
     * 新增专家库信息
     *
     * @param dto 专家库信息
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public String insertExpertInformationSheet(InsertExpertInformationSheetDto dto) throws Exception {
        //添加用户
        SysUser user = new SysUser();
        user.setNickName(dto.getExpertName());
        //设置默认密码test123
        user.setPassword(SecurityUtils.encryptPassword("test123"));
        user.setSex(dto.getSex());
        user.setEmail(dto.getEmail());
        user.setPhonenumber(dto.getPhoneNumber());
        user.setCreateBy(SecurityUtils.getUsername());
        user.setDelFlag("0");
        //专家以专家姓名的拼音来当用户名
        user.setUserName(SecurityUtils.getPinyin(dto.getExpertName()));
        List<SysUser> sysUserList = userService.selectUserList(new SysUser());
        List userNameList = Lists.newArrayList();
        sysUserList.stream().forEach(s->{
            String pinyin = SecurityUtils.getPinyin(dto.getExpertName());
            userNameList.add(s.getUserName());
            while (userNameList.contains(pinyin)){
                pinyin += "_i";
                user.setUserName(pinyin);
            }
        });
        //新增专家时，设置用户未专家
        user.setUserType("3");
        if (UserConstants.NOT_UNIQUE.equals(userService.checkUserNameUnique(user.getUserName()))) {
            throw new Exception("新增用户'" + user.getUserName() + "'失败，登录账号已存在");
        } else if (StringUtils.isNotEmpty(user.getPhonenumber())
                && UserConstants.NOT_UNIQUE.equals(userService.checkPhoneUnique(user))) {
            throw new Exception("新增用户'" + user.getUserName() + "'失败，手机号码已存在");
        } else if (StringUtils.isNotEmpty(user.getEmail())
                && UserConstants.NOT_UNIQUE.equals(userService.checkEmailUnique(user))) {
            throw new Exception("新增用户'" + user.getUserName() + "'失败，邮箱账号已存在");
        }
        //添加关联部门id
        List<SysDept> deptList = deptService.selectDeptList(new SysDept());
        deptList.forEach(data->{
            if (data.getDeptName().equals("评审专家")){
                user.setDeptId(data.getDeptId());
            }else if (data.getDeptName().equals("三方机构")){
                user.setDeptId(data.getDeptId());
            }

        });
        userService.insertUser(user);
        //增加用户与角色关系
        List<SysUserRole> list= new ArrayList<>();
        list.add(new SysUserRole(user.getUserId(),103L));
        sysUserRoleMapper.batchUserRole(list);
        ExpertInformationSheet bean = InsertExpertInformationSheetDto.of(dto);
        //同步文件对象
        ArrayList<YzqFile> fileArrayList = InsertExpertInformationSheetDto.toFile(bean, dto);
        if(StringUtils.isNotEmpty(fileArrayList)){
            fileService.batchInsertFile(fileArrayList);
        }

        //绑定账号id
        bean.setUserId(user.getUserId());
        //三方机构添加专家
        List<SysRole> roles = SecurityUtils.getLoginUser().getUser().getRoles();
        List<Long> collect = roles.stream().map(SysRole::getRoleId).collect(Collectors.toList());
        if (collect.contains(Constants.ROLE_TYPE_THIRD)) {
            SysDept sysDept = deptService.selectDeptById(SecurityUtils.getDeptId());
            QueryWrapper<OrganizationManagement> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("dept_id",sysDept.getDeptId())
                    .eq("is_delete", Constants.DELETE_STATUS_NORMAL);
            OrganizationManagement organizationManagement = organizationManagementMapper.selectOne(queryWrapper);
            if(StringUtils.isNotNull(organizationManagement)){
                bean.setOrmId(organizationManagement.getOrmId());
            }
        }

        //职业资格
        if(StringUtils.isNotEmpty(dto.getQualificationAddDtoS())){
            qualificationService.insertProfessionalQualification(bean.getExpertId(), dto.getQualificationAddDtoS());
        }

        //技术职称
        if(StringUtils.isNotEmpty(dto.getTechnicalTitleDtoS())){
            technicalTitleService.insertTechnicalTitle(bean.getExpertId(), dto.getTechnicalTitleDtoS());
        }
        //校验身份证信息
        String idNumber = bean.getIdNumber();
        if(StringUtils.isNotEmpty(idNumber)){
            int age = getAge(idNumber);
            bean.setAge(age);
        }
        expertInformationSheetMapper.insert(bean);
        return String.valueOf(bean.getExpertId());
    }

    /**
     * 修改专家库信息
     *
     * @param dto 专家库信息
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int updateExpertInformationSheet(UpdateExpertInformationSheetDto dto)
    {
        ExpertInformationSheet bean = UpdateExpertInformationSheetDto.of(dto);
        //校验身份证信息
        String idNumber = bean.getIdNumber();
        if (StringUtils.isNotEmpty(idNumber)){
            int age = getAge(idNumber);
            bean.setAge(age);
        }else {
            bean.setAge(null);
        }
        //同步文件对象
        ArrayList<YzqFile> fileArrayList = UpdateExpertInformationSheetDto.toFile(bean, dto);
        if(StringUtils.isNotEmpty(fileArrayList)){
            fileService.batchInsertFile(fileArrayList);
        }
        //更新技术职称（删除再添加）
        QueryWrapper<TechnicalTitle> titleQueryWrapper = new QueryWrapper<>();
        titleQueryWrapper.eq("expert_id",dto.getExpertId());
        titleQueryWrapper.eq("del_flag",TechnicalTitle.DELETE_STATUS_NORMAL);
        List<TechnicalTitle> technicalTitles = technicalTitleMapper.selectList(titleQueryWrapper);
        if(technicalTitles.size()<=0){
            technicalTitleService.insertTechnicalTitle(dto.getExpertId(), dto.getTechnicalTitleDtoS());
        }else{
            int resultTechnicalTitle =  technicalTitleMapper.delete(titleQueryWrapper);
            Assert.isTrue(resultTechnicalTitle >= 0,"技术职称删除失败!!!");
            //插入技术职称
            technicalTitleService.insertTechnicalTitle(dto.getExpertId(), dto.getTechnicalTitleDtoS());
        }
        //更新职业资格
        QueryWrapper<ProfessionalQualification> qualificationQueryWrapper = new QueryWrapper<>();
        qualificationQueryWrapper.eq("expert_id",dto.getExpertId());
        qualificationQueryWrapper.eq("del_flag",TechnicalTitle.DELETE_STATUS_NORMAL);
        List<ProfessionalQualification> qualifications = qualificationMapper.selectList(qualificationQueryWrapper);
        if (qualifications.size() <= 0){
            qualificationService.insertProfessionalQualification(dto.getExpertId(), dto.getQualificationAddDtoS());
        }else {
            int resultQualification = qualificationMapper.delete(qualificationQueryWrapper);
            Assert.isTrue(resultQualification >= 0,"职业资格删除失败!!!");
            //插入职业资格
            qualificationService.insertProfessionalQualification(dto.getExpertId(), dto.getQualificationAddDtoS());
        }

        //专家名称修改则更新 系统用户名称
        ExpertInformationSheetDetailVo expertInformationSheetDetailVo =
                expertInformationSheetMapper.selectExpertInformationSheetByExpertId(dto.getExpertId());
        if (null!=expertInformationSheetDetailVo&&expertInformationSheetDetailVo.getUserId()>0) {
            SysUser sysUser=userService.selectUserById(expertInformationSheetDetailVo.getUserId());
            if (null!=sysUser){
                sysUser.setNickName(dto.getExpertName());
                sysUser.setRoleIds(new Long[]{103L});
                sysUser.setPhonenumber(dto.getPhoneNumber());
                userService.updateUser(sysUser);
            }
        }
        return expertInformationSheetMapper.updateById(bean);
    }


    /**
     * 删除专家库信息信息
     *
     * @param expertId 专家库信息主键
     * @return 结果
     */
    @Override
    public int deleteExpertInformationSheetByExpertId(Long expertId)
    {
        ExpertInformationSheet bean = expertInformationSheetMapper.selectById(expertId);
        bean.setDelFlag("1");
        return expertInformationSheetMapper.updateById(bean);
    }

    @Override
    public List<Long> selectRandomOne(String peopleNumber,Long ormId,List<Long> expertIds,List<Long> collectExtractId) {
        return expertInformationSheetMapper.selectRandomOne(peopleNumber,ormId,expertIds,collectExtractId) ;
    }

    @Override
    public List<ExtractRuleBeginVo> selectListById(List<Long> list) {
        return expertInformationSheetMapper.selectListById(list);
    }

    /**
     * 列表查询
     * @param queryDto
     * @return
     */
    @Override
    public List<ExpertInformationSheetListVo> selectExpertInfoSheetList(QueryExpertInformationSheetDto queryDto) {
        //根据登录信息确认三方机构或大数据
        Long deptId = SecurityUtils.getLoginUser().getDeptId();
        LambdaQueryWrapper<OrganizationManagement> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(OrganizationManagement::getDeptId,deptId);
        OrganizationManagement organizationManagement = organizationManagementMapper.selectOne(queryWrapper);

        QueryWrapper<ExpertInformationSheet> expertInformationSheetQueryWrapper = new QueryWrapper<>();
        if (null!=queryDto&&StringUtils.equals("0",queryDto.getExpertType())){
            expertInformationSheetQueryWrapper.eq("del_flag","0");
        }else{
            expertInformationSheetQueryWrapper.isNull("orm_id").eq("del_flag","0");
        }
        List<ExpertInformationSheet> expertInformationSheetList = expertInformationSheetMapper.selectList(expertInformationSheetQueryWrapper);

        Long ormId = null;
        List<Long> expertIds = null;
        if (StringUtils.isNotNull(organizationManagement)) {
            ormId = organizationManagement.getOrmId();
        }else {
            expertIds = expertInformationSheetList.stream().map(ExpertInformationSheet::getExpertId).collect(Collectors.toList());
        }
        startPage();
        List<ExpertInformationSheetListVo> list =  expertInformationSheetMapper.selectExpertInfoSheetList(queryDto,ormId,expertIds);
        return  list;
    }

    @Override
    public List<Long> conditionSelect(ExpertInformationSheetDto dto,List<Long> collectExtractId) {
        Long deptId = SecurityUtils.getLoginUser().getDeptId();
        List<OrganizationManagement> organizationManagementList = organizationManagementService.lambdaQuery().eq(OrganizationManagement::getDeptId, deptId).list();
        //三方机构条件抽取专家
        Long ormId=null;
        if(StringUtils.isNotEmpty(organizationManagementList)){
            ormId=organizationManagementList.get(0).getOrmId();
        }
        return expertInformationSheetMapper.conditionSelect(dto,ormId,collectExtractId);
    }



}
